home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / lisp / kcl / akcl / akcl1615.lha / c / rel_rios.c < prev    next >
C/C++ Source or Header  |  1990-08-14  |  8KB  |  267 lines

  1.  
  2. /* Copyright William Schelter. All rights reserved.  This file does
  3. the low level relocation which tends to be very system dependent.
  4. It is included by the file sfasl.c
  5. */
  6.  
  7. typedef int (*FUNC)();
  8. extern int akcltoc;
  9. extern int toc_start;
  10. static int current_toc;
  11. static int ptrgl_offset = 0;
  12. static int  ptrgl_text;
  13.  
  14. static int akcltoc_used=0;
  15.  
  16. /* This is an alternating list of addresses x1,y1,x2,y2,... where
  17.    relocation entries for changing value in address x1 shold be read as changing
  18.    it in y1 */
  19.  
  20. static  int  toc_addresses_to_relocate [10];
  21. static  int *next_toc_addresses_to_relocate = toc_addresses_to_relocate ;
  22. static int akcltoc_thisload;
  23. static int begun_relocate = 0;
  24.  
  25. static int set_rel_bits(address,bits,val)
  26.      char *address;
  27.      int val;
  28.      int bits;
  29. { bits += 1;
  30.  if ( bits <= 16)
  31.    {unsigned short  y = *(unsigned short *)address ;
  32.     y = y &  (~0 << bits) ;
  33.     y |= (val & ~(~0 << bits));
  34.     *(unsigned short *)address = val;
  35.   }
  36.   else
  37.    {unsigned int  y = *(unsigned int *)address ;
  38.     y = y &  (~0 << bits) ;
  39.     y |= (val & ~(~0 << bits));
  40.     *(unsigned int *)address = y;
  41.   }
  42. }
  43.  
  44. /*
  45.  800b0000          l   r0,0x0(r11)  
  46.  90410014         st   r2,0x14(r1)  
  47.  7c0903a6      mtctr   r0           
  48.  804b0004          l   r2,0x4(r11)         
  49.  816b0008          l   r11,0x8(r11) 
  50.  4e800420       bctr                
  51. */
  52. int myptrgl[6] = {
  53.   0x800b0000, 0x90410014, 0x7c0903a6, 0x804b0004,
  54.   0x816b0008, 0x4e800420};
  55.  
  56. /* 7d8903a6      mtctr   r12 
  57.  4e800420       bctr
  58.  */
  59. static int jmp_r12[2] = { 0x7d8903a6, 0x4e800420};
  60.  
  61.   
  62. #define SYM_SMC(sym)  (((union auxent *)(sym+1))->x_csect.x_smclas)
  63. #define SYM_TOC_ADDR(sym)  (((union auxent *)(sym+1))->x_csect.x_parmhash)
  64. /* #define SYM_USED(sym)   (((union auxent *)(&sym[1]))->x_csect.x_snhash) */
  65. #define  TC_SYMBOL_P(sym) ((sym)->n_scnum == DATA_NSCN && NUM_AUX((sym)) && \
  66.                (SYM_SMC(sym) == XMC_TC0 ||  SYM_SMC(sym) == XMC_TC))
  67.                 
  68.  
  69.  
  70. int FIXtemp ;
  71. static int intcmp2(x,y)
  72.      int *x,*y;
  73. { return (*x - *y);
  74. }
  75.  
  76. #define  TOP6 (~0 << 26)
  77. #define  BR_IN_DATA_P(x) (((x) & TOP6) == (DBEGIN & TOP6))
  78.  
  79.  
  80. relocate()
  81. { struct syment *sym = &symbol_table[relocation_info.r_symndx];
  82.   char *where;
  83.   describe_sym(relocation_info.r_symndx);
  84.   where = the_start + relocation_info.r_vaddr;
  85.   dprintf (where has %x , *(int *)where);
  86.   dprintf(   at %x -->, where );
  87.  
  88.   if(begun_relocate == 0)
  89.     {int n =   next_toc_addresses_to_relocate - toc_addresses_to_relocate;
  90.        begun_relocate = 1;
  91.      FIXtemp = 0; /* dummy reference for export problem */
  92.      qsort((char *)toc_addresses_to_relocate, n/2 , 2*sizeof(int),  intcmp2);
  93.      next_toc_addresses_to_relocate
  94.        = toc_addresses_to_relocate;}
  95.  
  96.   switch(RELOC_RTYPE(relocation_info))
  97.     { int *q;
  98.  
  99.     case R_TOC:     /* TOC_ILodx */
  100.       set_rel_bits(where,RELOC_RLEN(relocation_info), sym->n_value -  toc_start) ;
  101.       break;
  102.     case R_POS:   /* Pos_Rel */
  103.  
  104.        if (where == *next_toc_addresses_to_relocate)
  105.      {where = next_toc_addresses_to_relocate [1];
  106.       next_toc_addresses_to_relocate +=  2;}
  107.  
  108.      if ( sym->n_scnum == N_UNDEF || TC_SYMBOL_P(sym))
  109.     set_rel_bits(where,RELOC_RLEN(relocation_info),  sym->n_value);
  110.      else
  111.        set_rel_bits(where,RELOC_RLEN(relocation_info), (*(int *)where)+ sym->n_value);
  112.  
  113.       break;
  114.     case R_BR:   /* Brn_Sel */
  115.  
  116.       {int link_bit = ((((int *)where)[0]) & 1);
  117.        if (((((int *)where)[0]) & TOP6 ) == 0x48000000)    /* bl or b relative */
  118.      {
  119.        if (((int *)where)[1] == 0x80410014) /* l   r2,0x14(r1) */
  120.          {int x = SYM_TOC_ADDR(sym);
  121.           if (x)
  122.         { ((int *)where)[0]  = 0x81820000 ; /*  l   r12,0x0(r2) */
  123.           set_rel_bits(where+2,15,x - toc_start);
  124.           (((int *)where)[1] = 0x48000000); /* b relative */
  125.           set_rel_bits(where+4, 0x19, ((int) jmp_r12) - ((int) where + 4 ));
  126.           ((int *)where)[1] |=  link_bit; /* link bit */
  127.           break;
  128.         }
  129.           else        /* must be ptrgl */
  130.         if  (BR_IN_DATA_P(sym->n_value))
  131.           {set_rel_bits(where, 0x19, sym->n_value - (int) where);
  132.            ((int *)where)[0] |=  link_bit; /* link bit */
  133.            break;}
  134.         }
  135.        else
  136.          if (BR_IN_DATA_P(sym->n_value))
  137.            {set_rel_bits(where, 0x19,  sym->n_value - (int) where);
  138.         ((int *)where)[0] |=  link_bit; /* link bit */
  139.         break;}}
  140.        else
  141.      FEerror("The type of Br_sel was new ",0,0);
  142.      }
  143.     default:
  144.       fprintf(stdout, "%d: unsupported relocation type.",
  145.           RELOC_RTYPE(relocation_info) );
  146.       FEerror("The relocation type was unknown",0,0);
  147.     }
  148.   dprintf( %x,*(int *)where);
  149.  
  150. }
  151.  
  152. fix_undef_toc_address(answ,sym,str)
  153.      char *str;
  154.      struct syment *sym;
  155.      struct node *answ;
  156.      /* undefined sym */
  157. { if (BR_IN_DATA_P(answ->address)) return;
  158.   if (answ->tc_offset == 0)
  159.     { answ->tc_offset = ( akcltoc + akcltoc_used - toc_start);
  160.       * ((int *)( akcltoc + akcltoc_used)) = answ->address;
  161.       akcltoc_used += sizeof(char *);
  162.     }
  163.  
  164.       if (NUM_AUX(sym))
  165.     SYM_TOC_ADDR(sym) =  (toc_start + answ->tc_offset);
  166.       else printf("symbol should have aux entry");
  167.   
  168.   return;
  169. }
  170.  
  171.       
  172.     
  173.     
  174.  
  175.  
  176. #ifdef DEBUG
  177. #undef describe_sym
  178. #define describe_sym(x) do{if(sfasldebug) describe_sym1(x);} while (0)
  179. describe_sym1(n)
  180. int n;
  181. {char *str;
  182.  char tem[9];
  183.  struct syment *sym;
  184.  sym= &symbol_table[n];
  185.  str= sym->n_zeroes == 0 ?
  186.    &my_string_table[sym->n_offset] :
  187.  (sym->n_name[SYMNMLEN -1] ?
  188.   /* MAKE IT NULL TERMINATED */
  189.   (strncpy(tem,sym->n_name,
  190.        SYMNMLEN),tem):
  191.   sym->n_name );
  192.  printf ("sym-index = %d table entry at %x",n,&symbol_table[n]);
  193.  printf("symbol is (%s):\nsymbol_table[n]._n._n_name %s\nsymbol_table[n]._n._n_n._n_zeroes %d\nsymbol_table[n]._n._n_n._n_offset %d\nsymbol_table[n]._n._n_nptr[0] %d\nsymbol_table[n]._n._n_nptr[n] %d\nsymbol_table[n].n_value %d\nsymbol_table[n].n_scnum %d nsymbol_table[n].n_type %d\nsymbol_table[n].n_sclass %d\nsymbol_table[n].n_numaux %d", str,
  194.     symbol_table[n]._n._n_name,
  195.     symbol_table[n]._n._n_n._n_zeroes ,
  196.     symbol_table[n]._n._n_n._n_offset ,
  197.     symbol_table[n]._n._n_nptr[0] ,
  198.     symbol_table[n]._n._n_nptr[1] ,
  199.     symbol_table[n].n_value ,
  200.     symbol_table[n].n_scnum ,
  201.     symbol_table[n].n_type ,
  202.     symbol_table[n].n_sclass ,
  203.     symbol_table[n].n_numaux );
  204. }
  205.  
  206. #endif 
  207.  
  208.  
  209.  
  210.  
  211. /* allocate toc space in the preallocated region starting at akcltoc.
  212.    If a symbol already has a toc entry, use that instead
  213.    */
  214.  
  215. setup_for_aix_load()
  216. { bzero(toc_addresses_to_relocate,sizeof(toc_addresses_to_relocate));
  217.   next_toc_addresses_to_relocate= toc_addresses_to_relocate;
  218.   akcltoc_thisload = akcltoc + akcltoc_used;
  219.   begun_relocate=0;
  220.  
  221. }
  222.  
  223. char *
  224. sym_name(sym)
  225.      struct syment *sym;
  226. {static char tem[SYMNMLEN +1];
  227.  char *name;
  228.  tem[SYMNMLEN] = '0';
  229.  name =  SYM_NAME(sym);
  230.  return name;}
  231.  
  232.          
  233.  
  234. allocate_toc(sym)
  235.  struct syment *sym;
  236.      /* sym is a symbol in the data section with an aux entry */ 
  237. { if (SYM_SMC(sym) == XMC_TC0)
  238.     { sym->n_value =  toc_start; return 1;}
  239.   if (SYM_SMC(sym) == XMC_TC)
  240.     {struct node *answ = find_sym(sym,0);
  241.      if (answ  && answ->tc_offset)
  242.        { sym->n_value = toc_start + answ->tc_offset;
  243.      return 1;}
  244.      {char *na = sym_name(sym);
  245. #ifdef SYM_USED      
  246.       if (TC_SYMBOL_P(sym) && SYM_USED(sym) == 0)
  247.     return 0;
  248. #endif
  249.       if (answ == 0 && *na  &&  *na != '_')
  250.     printf("(strange TC synbol %s[%d])",na,sym - symbol_table);}
  251.      {int old_value;
  252.       (*next_toc_addresses_to_relocate++) =  sym->n_value + start_address;
  253.       sym->n_value = akcltoc + akcltoc_used;
  254.       if (answ) answ->tc_offset = sym->n_value - toc_start;
  255.       (*next_toc_addresses_to_relocate++) = sym->n_value;
  256.       *((int *)(next_toc_addresses_to_relocate[-1])) =
  257.     *((int *)(next_toc_addresses_to_relocate[-2]));
  258.       akcltoc_used += sizeof(long int);
  259.       if (next_toc_addresses_to_relocate - toc_addresses_to_relocate
  260.       >= (sizeof(toc_addresses_to_relocate)/sizeof(int)))
  261.     FEerror("ran out");
  262.       if (akcltoc_used > 24000) FEerror("toc exhausted");
  263.       return 1;
  264.     }}
  265.   return 0;
  266. }
  267.